home *** CD-ROM | disk | FTP | other *** search
/ isnet Internet / Isnet Internet CD.iso / prog / hiz / 09 / 09.exe / adynware.exe / perl / lib / ftp.pl < prev    next >
Encoding:
Perl Script  |  1999-12-28  |  16.9 KB  |  853 lines

  1.  
  2. require 'chat2.pl';    # into main
  3. eval "require 'socket.ph'" || eval "require 'sys/socket.ph'"
  4.     || die "socket.ph missing: $!\n";
  5.  
  6.  
  7. package ftp;
  8.  
  9. if( defined( &main'PF_INET ) ){
  10.     $pf_inet = &main'PF_INET;
  11.     $sock_stream = &main'SOCK_STREAM;
  12.     local($name, $aliases, $proto) = getprotobyname( 'tcp' );
  13.     $tcp_proto = $proto;
  14. }
  15. else {
  16.     $pf_inet = 2;
  17.     $sock_stream = 1;
  18.     $tcp_proto = 6;
  19. }
  20.  
  21. $timeout = 30;
  22.  
  23. $timeout_read = 20 * $timeout;
  24.  
  25. $timeout_open = $timeout;
  26.  
  27. $ftp'response = "";
  28.  
  29. $ftp'ftpbufsize = 4096;
  30.  
  31. $ftp'hashevery = 1024;
  32. $ftp'hashnl = 70;
  33.  
  34. $real_site = "";
  35.  
  36. $ftp_show = 0;
  37. sub ftp'debug
  38. {
  39.     $ftp_show = $_[0];
  40. }
  41.  
  42. sub ftp'set_timeout
  43. {
  44.     $timeout = $_[0];
  45.     $timeout_open = $timeout;
  46.     $timeout_read = 20 * $timeout;
  47.     if( $ftp_show ){
  48.         print STDERR "ftp timeout set to $timeout\n";
  49.     }
  50. }
  51.  
  52.  
  53. sub ftp'open_alarm
  54. {
  55.     die "timeout: open";
  56. }
  57.  
  58. sub ftp'timed_open
  59. {
  60.     local( $site, $ftp_port, $retry_call, $attempts ) = @_;
  61.     local( $connect_site, $connect_port );
  62.     local( $res );
  63.  
  64.     alarm( $timeout_open );
  65.  
  66.     while( $attempts-- ){
  67.         if( $ftp_show ){
  68.             print STDERR "proxy connecting via $proxy_gateway [$proxy_ftp_port]\n" if $proxy;
  69.             print STDERR "Connecting to $site";
  70.             if( $ftp_port != 21 ){
  71.                 print STDERR " [port $ftp_port]";
  72.             }
  73.             print STDERR "\n";
  74.         }
  75.         
  76.         if( $proxy ) {
  77.             if( ! $proxy_gateway ) {
  78.                 $proxy_gateway = "internet-gateway";
  79.             }
  80.             if( $debug ) {
  81.                 print STDERR "using proxy services of $proxy_gateway, ";
  82.                 print STDERR "at $proxy_ftp_port\n";
  83.             }
  84.             $connect_site = $proxy_gateway;
  85.             $connect_port = $proxy_ftp_port;
  86.             $real_site = $site;
  87.         }
  88.         else {
  89.             $connect_site = $site;
  90.             $connect_port = $ftp_port;
  91.         }
  92.         if( ! &chat'open_port( $connect_site, $connect_port ) ){
  93.             if( $retry_call ){
  94.                 print STDERR "Failed to connect\n" if $ftp_show;
  95.                 next;
  96.             }
  97.             else {
  98.                 print STDERR "proxy connection failed " if $proxy;
  99.                 print STDERR "Cannot open ftp to $connect_site\n" if $ftp_show;
  100.                 return 0;
  101.             }
  102.         }
  103.         $res = &ftp'expect( $timeout,
  104.                     120, "service unavailable to $site", 0, 
  105.                                 220, "ready for login to $site", 1,
  106.                     421, "service unavailable to $site, closing connection", 0);
  107.         if( ! $res ){
  108.             &chat'close();
  109.             next;
  110.         }
  111.         return 1;
  112.     }
  113.     continue {
  114.         print STDERR "Pausing between retries\n";
  115.         sleep( $retry_pause );
  116.     }
  117.     return 0;
  118. }
  119.  
  120. sub ftp'open
  121. {
  122.     local( $site, $ftp_port, $retry_call, $attempts ) = @_;
  123.  
  124.     $SIG{ 'ALRM' } = "ftp\'open_alarm";
  125.  
  126.     local( $ret ) = eval "&timed_open( '$site', $ftp_port, $retry_call, $attempts )";
  127.     alarm( 0 );
  128.  
  129.     if( $@ =~ /^timeout/ ){
  130.         return -1;
  131.     }
  132.     return $ret;
  133. }
  134.  
  135. sub ftp'login
  136. {
  137.     local( $remote_user, $remote_password ) = @_;
  138.  
  139.     if( $proxy ){
  140.         &ftp'send( "USER $remote_user\@$site" );
  141.     }
  142.     else {
  143.         &ftp'send( "USER $remote_user" );
  144.     }
  145.         local( $val ) =
  146.                &ftp'expect($timeout,
  147.                230, "$remote_user logged in", 1,
  148.            331, "send password for $remote_user", 2,
  149.  
  150.            500, "syntax error", 0,
  151.            501, "syntax error", 0,
  152.            530, "not logged in", 0,
  153.            332, "account for login not supported", 0,
  154.  
  155.            421, "service unavailable, closing connection", 0);
  156.     if( $val == 1 ){
  157.         return 1;
  158.     }
  159.     if( $val == 2 ){
  160.         &ftp'send( "PASS $remote_password" );
  161.  
  162.         $val = &ftp'expect( $timeout,
  163.            230, "$remote_user logged in", 1,
  164.  
  165.            202, "command not implemented", 0,
  166.            332, "account for login not supported", 0,
  167.  
  168.            530, "not logged in", 0,
  169.            500, "syntax error", 0,
  170.            501, "syntax error", 0,
  171.            503, "bad sequence of commands", 0, 
  172.  
  173.            421, "service unavailable, closing connection", 0);
  174.         if( $val == 1){
  175.             return 1;
  176.         }
  177.     }
  178.     return 0;
  179. }
  180.  
  181. sub ftp'close
  182. {
  183.     &ftp'quit();
  184.     &chat'close();
  185. }
  186.  
  187. sub ftp'cwd
  188. {
  189.     local( $dir ) = @_;
  190.  
  191.     &ftp'send( "CWD $dir" );
  192.  
  193.     return &ftp'expect( $timeout,
  194.         200, "working directory = $dir", 1,
  195.         250, "working directory = $dir", 1,
  196.  
  197.         500, "syntax error", 0,
  198.         501, "syntax error", 0,
  199.                 502, "command not implemented", 0,
  200.         530, "not logged in", 0,
  201.                 550, "cannot change directory", 0,
  202.         421, "service unavailable, closing connection", 0 );
  203. }
  204.  
  205. sub ftp'dir_open
  206. {
  207.     local( $options ) = @_;
  208.     local( $ret );
  209.     
  210.     if( ! &ftp'open_data_socket() ){
  211.         return 0;
  212.     }
  213.     
  214.     if( $options ){
  215.         &ftp'send( "LIST $options" );
  216.     }
  217.     else {
  218.         &ftp'send( "LIST" );
  219.     }
  220.     
  221.     $ret = &ftp'expect( $timeout,
  222.         150, "reading directory", 1,
  223.     
  224.         125, "data connection already open?", 0,
  225.     
  226.         450, "file unavailable", 0,
  227.         500, "syntax error", 0,
  228.         501, "syntax error", 0,
  229.         502, "command not implemented", 0,
  230.         530, "not logged in", 0,
  231.     
  232.            421, "service unavailable, closing connection", 0 );
  233.     if( ! $ret ){
  234.         &ftp'close_data_socket;
  235.         return 0;
  236.     }
  237.     
  238.     
  239.     accept(NS,S) || die "accept failed $!";
  240.     
  241.     return 1;
  242. }
  243.  
  244.  
  245. sub ftp'dir_close
  246. {
  247.     local( $ret );
  248.  
  249.     $ret = &ftp'expect($timeout,
  250.             226, "", 1,     # transfer complete, closing connection
  251.             250, "", 1,     # action completed
  252.  
  253.             425, "can't open data connection", 0,
  254.             426, "connection closed, transfer aborted", 0,
  255.             451, "action aborted, local error", 0,
  256.             421, "service unavailable, closing connection", 0);
  257.  
  258.     &ftp'close_data_socket;
  259.  
  260.     if( ! $ret ){
  261.         return 0;
  262.     }
  263.  
  264.     return 1;
  265. }
  266.  
  267. sub ftp'quit
  268. {
  269.     $site_command_check = 0;
  270.     @site_command_list = ();
  271.  
  272.     &ftp'send("QUIT");
  273.  
  274.     return &ftp'expect($timeout, 
  275.         221, "Goodbye", 1,     # transfer complete, closing connection
  276.     
  277.         500, "error quitting??", 0);
  278. }
  279.  
  280. sub ftp'read_alarm
  281. {
  282.     die "timeout: read";
  283. }
  284.  
  285. sub ftp'timed_read
  286. {
  287.     alarm( $timeout_read );
  288.     return sysread( NS, $buf, $ftpbufsize );
  289. }
  290.  
  291. sub ftp'read
  292. {
  293.     $SIG{ 'ALRM' } = "ftp\'read_alarm";
  294.  
  295.     local( $ret ) = eval '&timed_read()';
  296.     alarm( 0 );
  297.  
  298.     if( $@ =~ /^timeout/ ){
  299.         return -1;
  300.     }
  301.     return $ret;
  302. }
  303.  
  304. sub ftp'get
  305. {
  306.     local($rem_fname, $loc_fname, $restart ) = @_;
  307.     
  308.     if ($loc_fname eq "") {
  309.         $loc_fname = $rem_fname;
  310.     }
  311.     
  312.     if( ! &ftp'open_data_socket() ){
  313.         print STDERR "Cannot open data socket\n";
  314.         return 0;
  315.     }
  316.  
  317.     if( $loc_fname ne '-' ){
  318.         local( $restart_at ) = &ftp'filesize( $loc_fname );
  319.         if( $restart && $restart_at > 0 && &ftp'restart( $restart_at ) ){
  320.             $restart = 1;
  321.             chmod( 0644, $loc_fname );
  322.         }
  323.         else {
  324.             $restart = 0;
  325.             unlink( $loc_fname );
  326.         }
  327.     }
  328.  
  329.     &ftp'send( "RETR $rem_fname" );
  330.     
  331.     local( $ret ) =
  332.         &ftp'expect($timeout, 
  333.                    150, "receiving $rem_fname", 1,
  334.  
  335.                    125, "data connection already open?", 0,
  336.  
  337.                    450, "file unavailable", 2,
  338.                    550, "file unavailable", 2,
  339.  
  340.            500, "syntax error", 0,
  341.            501, "syntax error", 0,
  342.            530, "not logged in", 0,
  343.  
  344.            421, "service unavailable, closing connection", 0);
  345.     if( $ret != 1 ){
  346.         print STDERR "Failure on RETR command\n";
  347.  
  348.         &ftp'close_data_socket;
  349.  
  350.         return 0;
  351.     }
  352.  
  353.  
  354.     accept(NS,S) || die "accept failed: $!";
  355.  
  356.     if( !open(FH, ($restart ? '>>' : '>') . $loc_fname) ){
  357.         print STDERR "Cannot create local file $loc_fname\n";
  358.  
  359.         &ftp'close_data_socket;
  360.  
  361.         return 0;
  362.     }
  363.  
  364.  
  365.     local( $start_time ) = time;
  366.     local( $bytes, $lasthash, $hashes ) = (0, 0, 0);
  367.     while( ($len = &ftp'read()) > 0 ){
  368.         $bytes += $len;
  369.         if( $strip_cr ){
  370.             $ftp'buf =~ s/\r//g;
  371.         }
  372.         if( $ftp_show ){
  373.             while( $bytes > ($lasthash + $ftp'hashevery) ){
  374.                 print STDERR '#';
  375.                 $lasthash += $ftp'hashevery;
  376.                 $hashes++;
  377.                 if( ($hashes % $ftp'hashnl) == 0 ){
  378.                     print STDERR "\n";
  379.                 }
  380.             }
  381.         }
  382.         if( ! print FH $ftp'buf ){
  383.             print STDERR "\nfailed to write data";
  384.             return 0;
  385.         }
  386.     }
  387.     close( FH );
  388.  
  389.     &ftp'close_data_socket;
  390.  
  391.     if( $len < 0 ){
  392.         print STDERR "\ntimed out reading data!\n";
  393.  
  394.         return 0;
  395.     }
  396.         
  397.     if( $ftp_show ){
  398.         if( $hashes && ($hashes % $ftp'hashnl) != 0 ){
  399.             print STDERR "\n";
  400.         }
  401.         local( $secs ) = (time - $start_time);
  402.         if( $secs <= 0 ){
  403.             $secs = 1; # To avoid a divide by zero;
  404.         }
  405.  
  406.         local( $rate ) = int( $bytes / $secs );
  407.         print STDERR "Got $bytes bytes ($rate bytes/sec)\n";
  408.     }
  409.  
  410.  
  411.     $ret = &ftp'expect($timeout, 
  412.         226, "Got file", 1,     # transfer complete, closing connection
  413.             250, "Got file", 1,     # action completed
  414.     
  415.             110, "restart not supported", 0,
  416.             425, "can't open data connection", 0,
  417.             426, "connection closed, transfer aborted", 0,
  418.             451, "action aborted, local error", 0,
  419.         421, "service unavailable, closing connection", 0);
  420.  
  421.     return $ret;
  422. }
  423.  
  424. sub ftp'delete
  425. {
  426.     local( $rem_fname, $val ) = @_;
  427.  
  428.     &ftp'send("DELE $rem_fname" );
  429.     $val = &ftp'expect( $timeout, 
  430.                250,"Deleted $rem_fname", 1,
  431.                550,"Permission denied",0
  432.                );
  433.     return $val == 1;
  434. }
  435.  
  436. sub ftp'deldir
  437. {
  438.     local( $fname ) = @_;
  439.  
  440. }
  441.  
  442. sub ftp'put
  443. {
  444.     local( $loc_fname, $rem_fname ) = @_;
  445.     local( $strip_cr );
  446.     
  447.     if ($loc_fname eq "") {
  448.         $loc_fname = $rem_fname;
  449.     }
  450.     
  451.     if( ! &ftp'open_data_socket() ){
  452.         return 0;
  453.     }
  454.     
  455.     &ftp'send("STOR $rem_fname");
  456.     
  457.     
  458.     local( $ret ) =
  459.     &ftp'expect($timeout, 
  460.         150, "sending $loc_fname", 1,
  461.  
  462.         125, "data connection already open?", 0,
  463.         450, "file unavailable", 0,
  464.  
  465.         532, "need account for storing files", 0,
  466.         452, "insufficient storage on system", 0,
  467.         553, "file name not allowed", 0,
  468.  
  469.         500, "syntax error", 0,
  470.         501, "syntax error", 0,
  471.         530, "not logged in", 0,
  472.  
  473.         421, "service unavailable, closing connection", 0);
  474.  
  475.     if( $ret != 1 ){
  476.         &ftp'close_data_socket;
  477.  
  478.         return 0;
  479.     }
  480.  
  481.  
  482.     
  483.     accept(NS,S) || die "accept failed: $!";
  484.     
  485.     if( !open(FH, "<$loc_fname") ){
  486.         print STDERR "Cannot open local file $loc_fname\n";
  487.  
  488.         &ftp'close_data_socket;
  489.  
  490.         return 0;
  491.     }
  492.     
  493.     while (<FH>) {
  494.         print NS ;
  495.     }
  496.     close(FH);
  497.     
  498.     &ftp'close_data_socket;
  499.     
  500.     
  501.     $ret = &ftp'expect($timeout, 
  502.         226, "file put", 1,     # transfer complete, closing connection
  503.         250, "file put", 1,     # action completed
  504.     
  505.         110, "restart not supported", 0,
  506.         425, "can't open data connection", 0,
  507.         426, "connection closed, transfer aborted", 0,
  508.         451, "action aborted, local error", 0,
  509.         551, "page type unknown", 0,
  510.         552, "storage allocation exceeded", 0,
  511.     
  512.         421, "service unavailable, closing connection", 0);
  513.     if( ! $ret ){
  514.         print STDERR "error putting $loc_fname\n";
  515.     }
  516.     return $ret;
  517. }
  518.  
  519. sub ftp'restart
  520. {
  521.     local( $restart_point, $ret ) = @_;
  522.  
  523.     &ftp'send("REST $restart_point");
  524.  
  525.  
  526.     $ret = &ftp'expect($timeout, 
  527.                350, "restarting at $restart_point", 1,
  528.                
  529.                500, "syntax error", 0,
  530.                501, "syntax error", 0,
  531.                502, "REST not implemented", 2,
  532.                530, "not logged in", 0,
  533.                554, "REST not implemented", 2,
  534.                
  535.                421, "service unavailable, closing connection", 0);
  536.     return $ret;
  537. }
  538.  
  539. sub ftp'type
  540. {
  541.     local( $type ) = @_;
  542.  
  543.     &ftp'send("TYPE $type");
  544.  
  545.  
  546.     $ret = &ftp'expect($timeout, 
  547.                200, "file type set to $type", 1,
  548.                
  549.                500, "syntax error", 0,
  550.                501, "syntax error", 0,
  551.                504, "Invalid form or byte size for type $type", 0,
  552.                
  553.                421, "service unavailable, closing connection", 0);
  554.     return $ret;
  555. }
  556.  
  557. $site_command_check = 0;
  558. @site_command_list = ();
  559.  
  560. sub ftp'site_commands
  561. {
  562.     local( $ret );
  563.     
  564.     if( !$site_command_check ){
  565.     
  566.         $site_command_check = 1;
  567.     
  568.         &ftp'send( "HELP SITE" );
  569.     
  570.         $ret = &ftp'expect( $timeout,
  571.             ".*HELP.*", "", "\$1",
  572.             214, "", "0",
  573.             202, "", "0" );
  574.     
  575.         if( $ret eq "0" ){
  576.             print STDERR "No response from HELP SITE\n" if( $ftp_show );
  577.         }
  578.     
  579.         @site_command_list = split(/\s+/, $ret);
  580.     }
  581.     
  582.     return @site_command_list;
  583. }
  584.  
  585. sub ftp'pwd
  586. {
  587.     local( $ret, $cwd );
  588.  
  589.     &ftp'send( "PWD" );
  590.  
  591.  
  592.     $ret = &ftp'expect( $timeout, 
  593.                257, "working dir is", 1,
  594.                500, "syntax error", 0,
  595.                501, "syntax error", 0,
  596.                502, "PWD not implemented", 0,
  597.                        550, "file unavailable", 0,
  598.  
  599.                421, "service unavailable, closing connection", 0 );
  600.     if( $ret ){
  601.         if( $ftp'response =~ /^257\s"(.*)"\s.*$/ ){
  602.             $cwd = $1;
  603.         }
  604.     }
  605.     return $cwd;
  606. }
  607.  
  608. sub ftp'mkdir
  609. {
  610.     local( $path ) = @_;
  611.     local( $ret );
  612.  
  613.     &ftp'send( "MKD $path" );
  614.  
  615.  
  616.     $ret = &ftp'expect( $timeout, 
  617.                257, "made directory $path", 1,
  618.                
  619.                500, "syntax error", 0,
  620.                501, "syntax error", 0,
  621.                502, "MKD not implemented", 0,
  622.                530, "not logged in", 0,
  623.                        550, "file unavailable", 0,
  624.  
  625.                421, "service unavailable, closing connection", 0 );
  626.     return $ret;
  627. }
  628.  
  629. sub ftp'chmod
  630. {
  631.     local( $path, $mode ) = @_;
  632.     local( $ret );
  633.  
  634.     &ftp'send( sprintf( "SITE CHMOD %o $path", $mode ) );
  635.  
  636.  
  637.     $ret = &ftp'expect( $timeout, 
  638.                200, "chmod $mode $path succeeded", 1,
  639.                
  640.                500, "syntax error", 0,
  641.                501, "syntax error", 0,
  642.                502, "CHMOD not implemented", 0,
  643.                530, "not logged in", 0,
  644.                        550, "file unavailable", 0,
  645.  
  646.                421, "service unavailable, closing connection", 0 );
  647.     return $ret;
  648. }
  649.  
  650. sub ftp'rename
  651. {
  652.     local( $old_name, $new_name ) = @_;
  653.     local( $ret );
  654.  
  655.     &ftp'send( "RNFR $old_name" );
  656.  
  657.  
  658.     $ret = &ftp'expect( $timeout, 
  659.                350, "", 1,
  660.                
  661.                500, "syntax error", 0,
  662.                501, "syntax error", 0,
  663.                502, "RNFR not implemented", 0,
  664.                530, "not logged in", 0,
  665.                        550, "file unavailable", 0,
  666.                        450, "file unavailable", 0,
  667.                
  668.                421, "service unavailable, closing connection", 0);
  669.  
  670.  
  671.     if( $ret ) {
  672.         &ftp'send( "RNTO $new_name" );
  673.     
  674.     
  675.         $ret = &ftp'expect( $timeout, 
  676.                        250, "rename $old_name to $new_name", 1, 
  677.  
  678.                    500, "syntax error", 0,
  679.                    501, "syntax error", 0,
  680.                    502, "RNTO not implemented", 0,
  681.                    503, "bad sequence of commands", 0,
  682.                    530, "not logged in", 0,
  683.                            532, "need account for storing files", 0,
  684.                            553, "file name not allowed", 0,
  685.                    
  686.                    421, "service unavailable, closing connection", 0);
  687.     }
  688.  
  689.     return $ret;
  690. }
  691.  
  692.  
  693. sub ftp'quote
  694. {
  695.       local( $cmd ) = @_;
  696.  
  697.       &ftp'send( $cmd );
  698.  
  699.       return &ftp'expect( $timeout, 
  700.               200, "Remote '$cmd' OK", 1,
  701.               500, "error in remote '$cmd'", 0 );
  702. }
  703.  
  704.  
  705. sub ftp'expectgot
  706. {
  707.     ($ftp'response, $ftp'fatalerror) = @_;
  708.     if( $ftp_show ){
  709.         print STDERR "$ftp'response\n";
  710.     }
  711. }
  712.  
  713. sub ftp'expect {
  714.     local( $ret );
  715.     local( $time_out );
  716.     local( $expect_args );
  717.     
  718.     $ftp'response = '';
  719.     $ftp'fatalerror = 0;
  720.  
  721.     @expect_args = ();
  722.     
  723.     $time_out = shift(@_);
  724.     
  725.     while( @_ ){
  726.         local( $code ) = shift( @_ );
  727.         local( $pre ) = '^';
  728.         if( $code =~ /^\d/ ){
  729.             $pre =~ "[.|\n]*^";
  730.         }
  731.         push( @expect_args, "$pre(" . $code . " .*)\\015\\n" );
  732.         shift( @_ );
  733.         push( @expect_args, 
  734.             "&ftp'expectgot( \$1, 0 ); " . shift( @_ ) );
  735.     }
  736.     
  737.     push( @expect_args, "^(.*)\\015\\n" );
  738.     push( @expect_args, "&ftp'expectgot( \$1, 0 ); 100" );
  739.     
  740.     
  741.     push( @expect_args, 'TIMEOUT' );
  742.     push( @expect_args, "&ftp'expectgot( \"timed out\", 1 ); 0" );
  743.     
  744.     push( @expect_args, 'EOF' );
  745.     push( @expect_args, "&ftp'expectgot( \"remote server gone away\", 1 ); 0" );
  746.     
  747.     if( $ftp_show > 9 ){
  748.         &printargs( $time_out, @expect_args );
  749.     }
  750.     
  751.     $ret = &chat'expect( $time_out, @expect_args );
  752.     if( $ret == 100 ){
  753.         push( @expect_args, "^.*\n" );
  754.         push( @expect_args, "100" );
  755.     
  756.         while( $ret == 100 ){
  757.             $ret = &chat'expect( $time_out, @expect_args );
  758.         }
  759.     }
  760.     
  761.     return $ret;
  762. }
  763.  
  764. sub ftp'open_data_socket
  765. {
  766.     local( $ret );
  767.     local( $hostname );
  768.     local( $sockaddr, $name, $aliases, $proto, $port );
  769.     local( $type, $len, $thisaddr, $myaddr, $a, $b, $c, $d );
  770.     local( $mysockaddr, $family, $hi, $lo );
  771.     
  772.     
  773.     $sockaddr = 'S n a4 x8';
  774.     chop( $hostname = `hostname` );
  775.     
  776.     $port = "ftp";
  777.     
  778.     ($name, $aliases, $proto) = getprotobyname( 'tcp' );
  779.     ($name, $aliases, $port) = getservbyname( $port, 'tcp' );
  780.     
  781.     ($a,$b,$c,$d) = unpack( 'C4', $chat'thisaddr );
  782.     
  783.     $this = $chat'thisproc;
  784.     
  785.     socket(S, $pf_inet, $sock_stream, $proto ) || die "socket: $!";
  786.     bind(S, $this) || die "bind: $!";
  787.     
  788.     $mysockaddr = getsockname(S);
  789.     ($family, $port, $myaddr) = unpack( $sockaddr, $mysockaddr );
  790.     
  791.     $hi = ($port >> 8) & 0x00ff;
  792.     $lo = $port & 0x00ff;
  793.     
  794.     listen( S, 5 ) || die "listen";
  795.     
  796.     &ftp'send( "PORT $a,$b,$c,$d,$hi,$lo" );
  797.     
  798.     return &ftp'expect($timeout,
  799.         200, "PORT command successful", 1,
  800.         250, "PORT command successful", 1 ,
  801.  
  802.         500, "syntax error", 0,
  803.         501, "syntax error", 0,
  804.         530, "not logged in", 0,
  805.  
  806.         421, "service unavailable, closing connection", 0);
  807. }
  808.     
  809. sub ftp'close_data_socket
  810. {
  811.     close(NS);
  812. }
  813.  
  814. sub ftp'send
  815. {
  816.     local($send_cmd) = @_;
  817.     if( $send_cmd =~ /\n/ ){
  818.         print STDERR "ERROR, \\n in send string for $send_cmd\n";
  819.     }
  820.     
  821.     if( $ftp_show ){
  822.         local( $sc ) = $send_cmd;
  823.  
  824.         if( $send_cmd =~ /^PASS/){
  825.             $sc = "PASS <somestring>";
  826.         }
  827.         print STDERR "---> $sc\n";
  828.     }
  829.     
  830.     &chat'print( "$send_cmd\r\n" );
  831. }
  832.  
  833. sub ftp'printargs
  834. {
  835.     while( @_ ){
  836.         print STDERR shift( @_ ) . "\n";
  837.     }
  838. }
  839.  
  840. sub ftp'filesize
  841. {
  842.     local( $fname ) = @_;
  843.  
  844.     if( ! -f $fname ){
  845.         return -1;
  846.     }
  847.  
  848.     return (stat( _ ))[ 7 ];
  849.     
  850. }
  851.  
  852. 1;
  853.